#!/usr/bin/env python
# vim:ts=4:sw=4:noet:

import sys
import time
from optparse import OptionParser
from c.base.version import InfoStrings
import c.base.support as support
import c.compiler.parse as parse
import c.compiler.mem as mem
import c.compiler.semantics as semantics
import c.compiler.cmg as cmg
from c.compiler.codegen import CodeGen
from c.compiler.optimise import Optimiser
from c.compiler.compiler import Compiler

sources = [
		"Object",
		"Magnitude",
		"Collection",
		"Dictionary",
		"Number",
		"Integer",
		"SmallInt",
		"Array",
		"OrderedArray",
		"ByteArray",
		"String",
		"Symbol",
		"Boolean",
		"False",
		"True",
		"Char",
		"Class",
		"Context",
		"Method",
		"Block",
		"Undefined",
		"System",
		"Time",
		"Robot",
		"DrawingRobot",
		"Colour",
		"Shape",
		"Polygon",
		"UnitTest",
		]

class ImageGen:
	def main(self):
		parser = OptionParser()
		parser.add_option("-o", "--output", dest="filename", default="data/default")
		parser.add_option("-n", "--nocfg", action="store_false", dest="config", default=True)
		parser.add_option("-q", "--quiet", action="store_false", dest="verbose", default=True)
		parser.add_option("-l", "--libpath", dest="libpath", default="src")
		options,args = parser.parse_args()
		self.run(options, args)

	def log(self, msg):
		if self.options.verbose:
			print msg

	def run(self, options, args):
		self.options = options
		stat = support.Status({"exceptions":True})
		p = parse.Parser(None, stat)
		classes = []
		self.log("Parsing")
		for a in sources:
			classes.extend(p.parseFile(options.libpath+"/"+a+".st"))
		for a in args:
			classes.extend(p.parseFile(a))
		self.log("Initialising memory")
		m = mem.Memory(stat)
		m.createBase()
		self.log("Checking semantics")
		s = semantics.Checker(m, stat)
		s.check(classes)
		s.markUnused(classes)
		
		self.log("Generating bytecode")
		bcstart = time.time()
		comp = Compiler(m, allClasses=classes)
		bcTotal = 0
		methCount = 0
		clshash = {}
		for cls in classes:
			clshash[cls.name] = cls
		for cls in classes:
			asm = ""
			for meth in cls.meths:
				comp.optimiseAndGenerateMethod(cls.spy, meth)
				bcTotal += len(meth.spy.bytecodes)
				methCount += 1
		bctime = time.time()-bcstart

		self.log("%d bytecodes, %d methods, %0.2f seconds" % (bcTotal,methCount,bctime))
		self.log("avg %0.1f bytes/method" % (bcTotal/float(methCount)))
		self.log("Writing image")
		m.readyForSave()
		ofn = options.filename
		oext = InfoStrings["imageExtension"]
		if options.config:
			size = m.save("%s.%s" % (ofn,oext), "%s.cfg" % ofn)
		else:
			size = m.save("%s.%s" % (ofn,oext))
		self.log("%dKB written" % (size/1024))
		self.log("Complete")
	
		return

if __name__=="__main__":
	ImageGen().main()
